
import traceback

from coffeetalk.client import iotpclient
from coffeetalk.protocol import ioml, requests, responses, iotypes
from coffeetalk.utilities import iologger

class BaseIOExtension(iotpclient.IOTPClient):
    
    def __init__(self,connectionconfig,path='/',log=iologger.IONullLogger()):
        
        self.connectionconfig = connectionconfig
        self.connectionconfig.userclass = 'System'
        
        self.path = path
        
        self.log = log
        # For testing purposes only
        if not isinstance(self.log,iologger.IONullLogger):
            logconfig = iologger.IOLoggerSettings()
            logconfig.Name.value = 'Base IOExtension'
            self.log.standardlogging = iologger.IOStdLogger(logconfig=logconfig)

        self._env = iotypes.Environment('0.0.0.0','baseioextension.py','System',str(id(self)),'0')      
        iotpclient.IOTPClient.__init__(self, config=connectionconfig,log=self.log)
    
    def handle_error(self,*args,**kwargs):
        print 'Handle_error: ' + str(args[3])
        print 'kwargs: ' + str(kwargs)
        
    def on_login(self):
        request = requests.AddExtension(path=self.path,on_success=self._handle_addextension,on_error=self.handle_error)
        self.send_request(request)
        self.extension_ready()
    
    def extension_ready(self):
        pass
    
    def _handle_addextension(self,*args,**kwargs):
        self.asynclient.process_message = self._process_request
        
    def send_response(self,response):
        self.asynclient.send_message(str(response))
        
    def _process_request(self,message):
        iomessage = ioml.IOML(iomlstring=message)
        path = iomessage.headelement.attribs['path']
        env = iotypes.Environment('','','','','',element=iomessage.headelement.childelements['ENV'])
        self.handle_request(env, path, iomessage)
    
    def handle_request(self,env,path,request):
        handler = request.headelement.attribs['type']
        if hasattr(self,'handle_' + handler):
            try:
                response = getattr(self,'handle_' + handler)(request,env,path)
            except:
                err = traceback.format_exc()
                self.log.log_error(iologger.DEBUG,'0.0.0.0',self.username,self.group,iologger.current_function(),'InternalError',err)
                response = responses.InternalError(requestid=request.headelement.attribs['requestid'],path=path,err='Request handler ' + str(handler) + ' caused an exception: ' + err)
        else:
            response = responses.InternalError(requestid=request.headelement.attribs['requestid'],path=path,err='Request handler ' + str(handler) + ' not implemented')
        if response is not None:
            print 'sending response: ' + str(response)
            self.send_response(response)
        
    def handle_Get(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
      
    def handle_Add(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')

    def handle_Delete(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
        
    def handle_Subscribe(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
              
    def handle_Unsubscribe(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
    
    def handle_AddMonitor(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
        
    def handle_DeleteMonitor(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
    
    def handle_AddAccess(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
    
    def handle_RemoveAccess(self,request,env,path):
        raise NotImplementedError('You must override ' + iologger.current_function(includefile=False) + ' in a derived class')
    
    def handle_AddExtension(self,request,env,path):
        return responses.InternalError(env=env,path=path,err='Adding extensions to an extension is forbidden')
        
    def handle_RemoveExtension(self,request,env,path):
        return responses.InternalError(env=env,path=path,err='Adding extensions to an extension is forbidden')
    
if __name__ == '__main__':
    
    connectionconfig = iotypes.Connection(name='Extension',username='BaseExtension',password='testing123',group='None',host='127.0.0.1',port='9091')
    chatter = BaseIOExtension(connectionconfig,path='/Applications/Test/Child 1/',log=iologger.IOLogger())
    chatter.connect()